#include<stdio.h>
#include<time.h>
#include<stdlib.h>
 
//проверка выигрыша 
int checkWinnings (char elements[3][3], char mansimbol) {   

    bool haswinner = false;
    //проверка первой диагонали      
    if ((elements[0][0] != ' ') && (elements[0][0] == elements[1][1]) && (elements[0][0] == elements[2][2])) {
        //если совпали, то победил тот, чьи это элементы и булл = true   
        if (elements[0][0] == mansimbol) {
            printf("Man has win\n");
            haswinner = true;
        } else {
            printf("Comp has win\n");
            haswinner = true;
        }
    }
    if (!haswinner) {                    
        //проверка второй диагонали
        if ((elements[0][2] != ' ') && (elements[0][2] == elements[1][1]) && (elements[1][1] == elements[2][0])) {
            //если совпали, то победил тот, чьи это элементы и булл = true   
            if (elements[0][2] == mansimbol) {
                printf("Man has win\n");
                haswinner = true;
            } else {
                printf("Comp has win\n");
                haswinner = true;
            }  
        }           
    }
    if (!haswinner) {                    
        //проверка столбцов
        for (int j = 0; j < 3; j++) {
            if ((elements[0][j] != ' ') && (elements[0][j] == elements[1][j]) && (elements[1][j] == elements[2][j])) {
                if (elements[0][j] == mansimbol) {
                    printf("Man has winn\n");
                    haswinner = true;
                    break; 
                } else {
                    printf("Comp has winn\n");
                    haswinner = true;
                    break;
                  } 
             }
        } 
    }
    if (!haswinner) {  
        //проверка строк
        for (int i = 0; i < 3; i++) {
            if ((elements[i][0] != ' ') && (elements[i][0] == elements[i][1]) && (elements[i][0] == elements[i][2])) {
                if (elements [i][0] == mansimbol) {
                    printf("Man has winn\n");
                    haswinner = true;
                    break; 
                } else {
                    printf("Comp has winn\n");
                    haswinner = true;
                    break;
                } 
            }
        }
    }

    return haswinner;
}                               

   //правило 1: Занимать цеетральную клетку в первую очердь, если она не занята
   //Правило 2: Завести "опасные позиции"(два в ряд) и проверять после каждого хода их наличие. Если их нет - "наступать"
   //Правило 3: Если человек занял среднюю клетку, то первый ход - рандомный ход 
 
 
//Если у 2-х элементов человека индексы столбцов или строк равны, то это опасная позиция
int ChekDP (char field[3][3], bool compsimbol,bool mansimbol, int coursecount,int a,int b) {
    bool DangerousPosition = false; // Опасная позиция
    int m=0;
    int n=0;
    int Where = 0; //Показатель того, где опасная позиция
    if (((field[a][b] == field[m][n]) && ((a == m)) || (b == n)) && (field[a][b] == mansimbol)) {
        DangerousPosition = true;
        Where = 1;
    }
    if (((field[0][0] == field[1][1]) || (field[0][0] == field[2][2]) || (field[1][1] == field[2][2])) && ((field[0][0] == mansimbol) || (field[1][1] == mansimbol))) {
        DangerousPosition = true;
        Where = 2;
    }
    if (((field[0][2] == field[1][1]) || (field[0][2] == field[2][0]) || (field[1][1] == field[2][0])) && ((field[0][2] == mansimbol) || (field[1][1] == mansimbol))) {
        DangerousPosition = true;
        Where = 3;
    }
    return (DangerousPosition && Where);
}

//Если первый ход и центральная клетка занята, то ставим символ рандомно. Если она свободна - скорее занимать ее
int SmartMove (char field[3][3], bool compsimbol,bool mansimbol, int coursecount, int a, int b, int x, int y,bool Where,bool DangerousPosition ) {
    bool SenterOur = false;
    if ((compsimbol == 'x') && (coursecount == 0)) {
        field[1][1] = compsimbol;
        SenterOur == true;
    } else {
        do { 
            y = rand () % 3;
            x = rand () % 3;
        } while (field[y][x] != ' '); 
        field[y][x] = compsimbol;
    }                
    //Если количество ходов человека >= 2 проверяем наличие опасных позиций 
    if ((mansimbol == 'x') && (coursecount >= 3)) {
        ChekDP(field,compsimbol,mansimbol,coursecount,a,b);
    }
    if ((mansimbol == 'o') && (coursecount >= 4)) {
        ChekDP( field,compsimbol, mansimbol,coursecount,a,b);
    }
    //Если они есть, начинаем защищаться
    if (dangerousPosision == true) {
        if (Where == 1) {
            if (b == n) {
                do {
                    p = rand () % 3;
                    field[p][b] = compsimbol;
                } while (field[p][b] != ' ');
             if (a == m) {
                do {
                    p = rand () % 3;
                    field[a][p] = compsimbol;
                } while (field[a][p] != ' ');
             }
           }
        }
        if ((Where == 2) && (SenterOur == false)) {
            if ((field[0][0] == field[1][1]) && (field[1][1] == mansimbol)) {
                field[0][2] = compsimbol;
            }
            if ((field[1][1] == field[2][0]) && (field[2][0] == mansimbol)) {
                field[0][2] = compsimbol;
            }
        }
        if ((Where == 3) && (SenterOur == false)) {
            if ((field[0][2] == field[1][1]) && (field[1][1] == mansimbol)) {
                field[2][0] = compsimbol;
            }
            if ((field[1][1] == field[2][0]) && (field[1][1] == mansimbol)) {
                field[0][2] = compsimbol;
            }
        }
    } else { //Еcли их нет, то начинаем атаковать
        //Если у нас есть 2 элемента в ряд, то ставим третий
        int c = 0;
        if (((field[a][b] == field[m][n]) && ((a == m)) || (b == n)) && (field[a][b] == compsimbol)) {
            c = 1;
            if (b == n) {
                do {
                    p = rand () % 3;
                    field[p][b] = compsimbol;
                } while (field[p][b] != ' ');
                if (a == m) {
                    do {
                        p = rand () % 3;
                        field[a][p] = compsimbol;
                    } while (field[a][p] != ' ');
                }
            }
        } 
        if (((field[0][0] == field[1][1]) || (field[0][0] == field[2][2]) || (field[1][1] == field[2][2])) && ((field[0][0] == compsimbol) || (field[1][1] == compsimbol))) {
            c = 2;
            if ((field[0][0] == field[1][1])) && (field[1][1] == sompsimbol)) {
                field[0][2] = compsimbol;
            }
            if ((field[1][1] == field[2][0])) && (field[2][0] == compsimbol)) {
                field[0][2] = compsimbol;
            }   
        }
        if (((field[0][2] == field[1][1]) || (field[0][2] == field[2][0]) || (field[1][1] == field[2][0])) && ((field[0][2] == compsimboll) || (field[1][1] == compsimbol))) {
            c = 3;
            if ((field[0][2] == field[1][1]) && (field[1][1] == compsimbol)) {
                field[2][0] = compsimbol;
            }
            if ((field[1][1] == field[2][0]) && (field[1][1] == compsimbol)) {
                field[0][2] = compsimbol;
            }    
        }
        //Если таких нет, то:
        if ((c != 1) && (c != 2) && (c != 3)) {
            //Если центральная клетка наша, то ставим знак рандомно
            if (SenterOur == true) {
                do { 
                    y = rand () % 3;
                    x = rand () % 3
                } while (field[y][x] != ' '); 
                field[y][x] = compsimbol;
            //Если нет, то ставим элемент в тот столбиц или строку (зависит от расположения элементов человека), где стоит любой наш
            } 
            if (((field[0][0] == field[0][1]) || (field[0][0] == field[0][2]) || (field[0][2] == field[0][1]) && ((field[0][0] == compsimbol) || (field[0][2] == compsimbol))) {
                if (field[0][0] == ' ') {
                    field[0][0] = compsimbol;
                }
                if (field[0][1] == ' ') {
                    field[0][1] = compsimbol;
                }
                if (field[0][2] == ' ') {
                    field[0][2] = compsimbol;
                }     
            }
            if (((field[2][0] == field[2][1]) || (field[2][0] == field[2][2]) || (field[2][2] == field[2][1]) && ((field[2][0] == compsimbol) || (field[2][2] == compsimbol))) {
                if (field[2][0] == ' ') {
                    field[2][0] = compsimbol;
                }
                if (field[2][1] == ' ') {
                    field[2][1] = compsimbol;
                }
                if (field[2][2] == ' ') {
                    field[2][2] = compsimbol;
                }   
            } 
         }
     }
 }
                       
            
               
int main() {                                        

    srand(time(NULL));
    //булевская переменная для наличия победителя 
    bool haswinner = false;
    //выстраивается поле 3 на 3 (двойной массив в виде таблицы с пустыми клетками вместо элементов)
    char field[3][3];
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            field[i][j] = ' ';
        }
    }
    //компьютер спрашивает человека, чем он будет играть (далее вместо цифры помещаем в массив х или о)
    char mansimbol = 0;
    char compsimbol = 0;
    bool mansCourse = false; 
    printf("Select a symbol - x or o: ");
    scanf("%c", &mansimbol);
    bool manFirst; 
    if (mansimbol == 'x') {
        mansCourse = true; 
        compsimbol = 'o';
    } else {
        mansCourse = false;
        compsimbol = 'x';
    }
    int y = 0;
    int x = 0;
    int a = 0;
    int b = 0; 
    int courseCounts = 0;//запомнить число ходов: 0
    //цикл, пока поле не кончится или кто-нибудь не победит
    while (!haswinner && courseCounts <= 9) {
        //если ход человека, то человек вводит, координаты, куда он хочет поставить знак
        if (mansCourse) {
            do {
                printf("Please, enter coordinates: ");
                scanf("%i %i", &y, &x);
            } while (field[y][x] != ' ' );
        field[y][x] = mansimbol;
        a = y;
        b = x;
        }
        /*//Вывести игровое поле
        if ((courseCounts != 0) && (mansimbol == 'x')) { 
            printf("\n");
            for (int i = 0; i < 3; i++) {
                printf("|");
                for (int j = 0; j < 3; j++) {
                    printf("%c", field[i][j]);
                    printf("|"); 
                }
                printf("\n");
            }
         }  */ 
        //к числу ходов прибавить 1
        courseCounts++;
        //проверка выигрыша
        haswinner = checkWinnings(field, mansimbol);
        //если поле не кончилось, то компьютер рандомно ставит свой знак
        if (courseCounts != 9 && haswinner == false) {
            /*do { 
                y = rand () % 3;
                x = rand () % 3;
            } while (field[y][x] != ' '); 
        field[y][x] = compsimbol;*/
        SmartMove(field,compsimbol,mansimbol,coursecount,a,b,x,y,DangerousPosition,Where);
        }                
        mansCourse = true;
        //к числу ходов прибавить 1   
        courseCounts++;
        //Вывести игровое поле
        if (haswinner == false) {
            printf("\n");
            for (int i = 0; i < 3; i++) {
                printf("|");
                for (int j = 0; j < 3; j++) {
                    printf("%c", field[i][j]);
                    printf("|"); 
                }
                printf("\n");
            }
        }
        //проверка выигрыша и выход из цикла, если кто-то выиграл
        if (haswinner == false) {
            haswinner = checkWinnings(field, mansimbol);
        }    
    }
    if (haswinner == false) {
        printf("No one won\n");
    }
    return 0;
} 
            
            
            
            
            
            
            
            

